package com.jinzhi.jzweb.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.utils.ApiResult;
import com.jinzhi.common.utils.Result;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.domain.vo.Data7Vo;
import com.jinzhi.jzweb.domain.vo.TotalVo;
import com.jinzhi.jzweb.domain.vo.Data2Vo;
import com.jinzhi.jzweb.service.*;
import com.jinzhi.jzweb.utils.RedisUtil;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author mengzhichao
 * @create 2024-07-03-14:41
 */

@RestController
@RequestMapping("/jzweb/dataStatistics")
public class DataStatisticsController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private StuSignUpService stuSignUpService;

    @Autowired
    private SysBrandService sysBrandService;

    @Autowired
    private CoursesService coursesService;

    @Autowired
    private OrganizationRolesService organizationRolesService;

    @Autowired
    private TrainingCertificatesService trainingCertificatesService;

    private static String bs = "-";

    @Autowired
    private OrganizationNewsService organizationNewsService;

    @Autowired
    private ExaminationAnswerSheetPracticeService examinationAnswerSheetPracticeService;


    @Autowired
    private DictService dictService;

    @Autowired
    private CertificationBatchService certificationBatchService;

    @Autowired
    private UserQrService userQrService;



//    // 定义字符集：包含数字、大写字母和小写字母
//    private static final String CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

//    /**
//     * 生成指定长度的随机字符串
//     * @param length 字符串长度
//     * @return 随机字符串
//     */
//    public static String generateRandomCode(int length) {
//        if (length <= 0) {
//            throw new IllegalArgumentException("长度必须大于0");
//        }
//
//        Random random = new Random();
//        StringBuilder sb = new StringBuilder(length);
//
//        for (int i = 0; i < length; i++) {
//            // 从字符集中随机选择一个字符
//            int index = random.nextInt(CHARACTERS.length());
//            sb.append(CHARACTERS.charAt(index));
//        }
//
//        return sb.toString();
//    }
//
//


    @GetMapping("/getDropDown")
    private Result<List<String>> getDropDown(){
        List list =new ArrayList();
        list.add("政府单位");
        list.add("学校");
        list.add("企业");
        list.add("其它");
        return Result.ok(list);
    }



    @GetMapping("/getUserCode")
    public Result<?> getUserCode(String phone,String name,String source){
//        String code = generateRandomCode(7);

        Integer code =0;
        Wrapper<UserQrDO> wrapper =new EntityWrapper();
        wrapper.eq("phone",phone);
        List<UserQrDO> userQrDO = userQrService.selectList(wrapper);

        if (userQrDO.size()>0){
            return Result.ok("您的序列号为："+userQrDO.get(0).getCode());
        }else {
            wrapper =new EntityWrapper().orderBy("code");
            List<UserQrDO> userQrMax = userQrService.selectList(wrapper);
            if (userQrMax.size()>0){
                code = Integer.valueOf(userQrMax.get(userQrMax.size() - 1).getCode()) + 1;
            }
            UserQrDO newUserQrDO =new UserQrDO();
            newUserQrDO.setCode(String.valueOf(code));
            newUserQrDO.setPhone(phone);
            newUserQrDO.setCreaterDate(new Date());
            newUserQrDO.setName(name);
            newUserQrDO.setSource(source);
            userQrService.insert(newUserQrDO);
        }
        return Result.ok("您的序列号为："+code);
    }















    /**
     * 统计图第一部分：1.总用户数量，2.试点院校数量，3.考核站点数量，4.产业学院数量，5.实体门店数量，6.考评学生数量，7.合作企业数量，8.合作省份数量
     * @return
     */
    @GetMapping("/data1")
    public Result<?> data1() {
        Map map =new HashMap();

        //查询总用户数量
        int userTotal = userService.selectCount(null);
        map.put("userTotal",userTotal);

        //查询试点院校数量
        map.put("sdyxTotal",getDictByType("sdyxTotal","试点院校数量"));

        //查询考核站点数量
        Page<OrganizationNewsDO> page = organizationNewsService.selKhzd("", 1, 100000);
        map.put("khzdTotal",page.getTotal());

        //查询产业学院数量
        map.put("collegeTotal",getDictByType("collegeTotal","产业学院数量"));

        //实体门店数量
        map.put("shopTotal",getDictByType("shopTotal","实体门店数量"));

        //考评学生总数
        int stuSignTotal = stuSignUpService.selstuSignUpCount();

        String kprs = getDictByType("sjdp_kprs", "数据大屏-考评人数");
        if (kprs!=null){
            if (!kprs.equals("0")){
                map.put("stuSignTotal",Integer.valueOf(kprs));
            }else {
                map.put("stuSignTotal",stuSignTotal);
            }
        }

        //合作企业数量
        int brandTotal = sysBrandService.selectCount(null);
        brandTotal = brandTotal + 401; //加上指定的数量
        map.put("brandTotal",brandTotal);

        //合作企业省份数量
        List<Map<Object, Object>> hzqy = trainingCertificatesService.selTrainingStuCount();
        map.put("brandProvinceTotal",hzqy.size() - 4);

        return Result.ok(map);
    }

    public String getDictByType(String type,String name){
        Map map = new HashMap();
        map.clear();
        map.put("type", type);
        map.put("name", name);
        return dictService.selDicBy(map);
    }


    public static long calculateSecondsUntil11PM(LocalDateTime currentDateTime) {
        // 定义今天晚上11点的时间
        LocalDateTime elevenPM = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.of(23, 0));

        // 如果当前时间超过或等于今天晚上11点，则返回到明天晚上11点的秒数差
        if (currentDateTime.isAfter(elevenPM) || currentDateTime.equals(elevenPM)) {
            LocalDateTime nextDayElevenPM = elevenPM.plusDays(1);
            return ChronoUnit.SECONDS.between(currentDateTime, nextDayElevenPM);
        } else {
            // 如果当前时间在今天晚上11点之前，则返回到今天晚上11点的秒数差
            return ChronoUnit.SECONDS.between(currentDateTime, elevenPM);
        }
    }


    // 封装的方法，用于统计省份数量
    private static int countProvinces(List<SysBrandDO> sysBrandProvinceDOS) {
        return (int) sysBrandProvinceDOS.stream()
                .map(SysBrandDO::getProvince)
                .distinct()
                .count();
    }



        /**
         *
         * @param sysBrandDOList
         * @return
         */
    private List<SysBrandDO> updateSysBrand(List<SysBrandDO> sysBrandDOList){
        for (int i=0;i<sysBrandDOList.size();i++){
            sysBrandDOList.get(i).setProvince(extractProvince(sysBrandDOList.get(i).getWorkAddress()));
        }
        return sysBrandDOList;
    }


    //通过正则表达式获取省份信息，获取不到返回未知
    public static String extractProvince(String address) {
        // 定义省份正则表达式
        String regex = "(北京|天津|上海|重庆|河北|山西|内蒙古|辽宁|吉林|黑龙江|江苏|浙江|安徽|福建|江西|山东|河南|湖北|湖南|广东|" +
                "广西|海南|四川|贵州|云南|西藏|陕西|甘肃|青海|宁夏|新疆|台湾|香港|澳门)";

        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(address);

        // 查找第一个匹配项作为省份信息
        if (matcher.find()) {
            return matcher.group();
        } else {
            return "未知";
        }
    }




    /**
     * 统计图第二部分，考核站点查询
     */
    @GetMapping("/data2")
    @Transactional
    public ApiResult<?> data2(String name,int current, int number) {
        Page<OrganizationNewsDO> page = organizationNewsService.selKhzd(name, current, number);
        for (int i=0;i<page.getRecords().size();i++){
            OrganizationNewsDO organizationNewsDO = page.getRecords().get(i);
            if (organizationNewsDO.getRoleType() == null){
                organizationNewsDO.setRoleType("幼儿照护");
            }
            if (organizationNewsDO.getRoleType().equals("幼儿照护")){
                EntityWrapper<CertificationBatchDO> wrapper = new EntityWrapper<>();
                wrapper.like("name",organizationNewsDO.getName()).and().like("name","产后恢复");
                List<CertificationBatchDO> certificationBatchDOS = certificationBatchService.selectList(wrapper);
                if (certificationBatchDOS!=null){
                    organizationNewsDO.setRoleType("幼儿照护,产后恢复");
                }
            }
            if (organizationNewsDO.getRoleType().equals("产后恢复")){
                EntityWrapper<CertificationBatchDO> wrapper = new EntityWrapper<>();
                wrapper.like("name",organizationNewsDO.getName()).and().like("name","幼儿照护");
                List<CertificationBatchDO> certificationBatchDOS = certificationBatchService.selectList(wrapper);
                if (certificationBatchDOS!=null){
                    organizationNewsDO.setRoleType("幼儿照护,产后恢复");
                }
            }
        }
        return ApiResult.success(page);
    }




    /**
     * 统计图第二部分，考评人数查询
     */
    @GetMapping("/data2details")
    @Transactional
    public ApiResult<?> data2details(String name) {

        List<Data2Vo> list = stuSignUpService.selstuSignUpCountByName(name);//查询前五年数据

        System.out.println("data2+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++："+list);

        Integer zj = 0;
        List<Data2Vo> rstList =new ArrayList<>();
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 获取当前年份
        int currentYear = currentDate.getYear();
        for (int i = 0; i < 5; i++) {
            rstList.add(creatDataObject(currentYear-i));
        }
        for (int i=0;i<5;i++){
            if (i >= 0 && i < list.size() && list.get(i) != null) {
                Data2Vo newData2Vo =new Data2Vo();
                if (list.get(i).getYear() == 2024){
                    newData2Vo.setHgl(list.get(i).getHgl()); //合格率
                    newData2Vo.setYear(list.get(i).getYear()); //年份
                    newData2Vo.setStuTotal(list.get(i).getStuTotal()); //人数
                    rstList.set(0,newData2Vo);
                }
                if (list.get(i).getYear() == 2023){
                    newData2Vo.setHgl(list.get(i).getHgl()); //合格率
                    newData2Vo.setYear(list.get(i).getYear()); //年份
                    newData2Vo.setStuTotal(list.get(i).getStuTotal()); //人数
                    rstList.set(1,newData2Vo);
                }
                if (list.get(i).getYear() == 2022){
                    newData2Vo.setHgl(list.get(i).getHgl()); //合格率
                    newData2Vo.setYear(list.get(i).getYear()); //年份
                    newData2Vo.setStuTotal(list.get(i).getStuTotal()); //人数
                    rstList.set(2,newData2Vo);
                }
                if (list.get(i).getYear() == 2021){
                    newData2Vo.setHgl(list.get(i).getHgl()); //合格率
                    newData2Vo.setYear(list.get(i).getYear()); //年份
                    newData2Vo.setStuTotal(list.get(i).getStuTotal()); //人数
                    rstList.set(3,newData2Vo);
                }
                if (list.get(i).getYear() == 2020){
                    newData2Vo.setHgl(list.get(i).getHgl()); //合格率
                    newData2Vo.setYear(list.get(i).getYear()); //年份
                    newData2Vo.setStuTotal(list.get(i).getStuTotal()); //人数
                    rstList.set(4,newData2Vo);
                }
            }
        }

        Map map =new HashMap();
        map.put("zj",rstList.get(0).getStuTotal() + rstList.get(1).getStuTotal()+rstList.get(2).getStuTotal()+rstList.get(3).getStuTotal()+rstList.get(4).getStuTotal());
        map.put("list",rstList);
        return ApiResult.success(map);
    }

    public Data2Vo creatDataObject(int year){
        Data2Vo data2Vo =new Data2Vo();
        data2Vo.setYear(year);
        data2Vo.setHgl("0");
        data2Vo.setStuTotal(0);
        return data2Vo;
    }




    /**
     * 统计图第二部分，师资人数查询
     */
    @GetMapping("/data2details2")
    @Transactional
    public ApiResult<?> data2details2(int current , int number ,String name) {
        Page<TrainingCertificatesDO> trainingCertificatesDOPage = trainingCertificatesService.selData2Vo(current,number,name);
        List<TrainingCertificatesDO> records = trainingCertificatesDOPage.getRecords();
        if (records != null) {
            int startNumber = (current - 1) * number + 1; // 计算起始序号

            for (int i = 0; i < records.size(); i++) {
                records.get(i).setNumber(startNumber + i); // 设置序号
            }
        }
        return ApiResult.success(trainingCertificatesDOPage);
    }







    /**
     * 统计图第三部分，合作企业统计
     * @param sysBrandDTO
     * @return
     */
    @GetMapping("/data3")
    public Result<Page<SysBrandDO>> data3(SysBrandDO sysBrandDTO){
        // 查询列表数据
        EntityWrapper<SysBrandDO> wrapper = new EntityWrapper<>();
        wrapper.orderBy("create_time",false);
        if(StringUtils.isNotBlank(sysBrandDTO.getBrandName())){
            wrapper.eq("brand_name",sysBrandDTO.getBrandName());
        }

        Page<SysBrandDO> page = sysBrandService.selectPage(getPage(SysBrandDO.class),wrapper
        );
        List list = new ArrayList();
        for (int i = 0; i < page.getRecords().size(); i++) {
            SysBrandDO obj = (SysBrandDO) page.getRecords().get(i);
            if (obj.getUserId()!=null && !obj.getUserId().equals("")){
                UserDO userDO = userService.selectById(obj.getUserId());
                obj.setUserName(userDO.getName());
            }
            obj.setProvince(extractProvince(obj.getWorkAddress()));
            list.add(obj);
        }
        page.setRecords(list);
        return Result.ok(page);
    }




    /**
     * 统计图第四部分，考评员，督导员统计
     */
    @GetMapping("/data4")
    public Result<Map> data4(){
        Map map =new HashMap();
        Integer kpyToatl = trainingCertificatesService.selTrainingCertificatesByName("考评员");
        kpyToatl = kpyToatl + 12941;
        map.put("kpyToatl",kpyToatl);
        Integer duyToatl = trainingCertificatesService.selTrainingCertificatesByName("督导员");
        map.put("ddyToatl",duyToatl);
        return Result.ok(map);
    }





    /**
     * 统计图第五部分，考评人数统计，师资人数统计
     * type == 1：考评人数统计
     * type == 2：师资人数统计
     */
    @GetMapping("/data5")
    public Result<TotalVo> data5(int type){
        String key  = "data5"+type;
        if (type == 1){
            List<Map<Object, Object>> data = (List<Map<Object, Object>>) RedisUtil.get(key);
            if (data!=null) {
                return Result.ok(formatData(data,type));
            }
            List<Map<Object, Object>> map = stuSignUpService.selProvincestuSignUpCount();
            RedisUtil.set(key,map,calculateSecondsUntil11PM(LocalDateTime.now()));
            return Result.ok(formatData(map,type));
        }else {
            List<Map<Object, Object>> data = (List<Map<Object, Object>>) RedisUtil.get(key);
            if (data!=null) {
                return Result.ok(formatData(data,type));
            }
            List<Map<Object, Object>> map = trainingCertificatesService.selTrainingStuCount();
            RedisUtil.set(key,map,calculateSecondsUntil11PM(LocalDateTime.now()));
            return Result.ok(formatData(map,type));
        }
    }





    /**
     * 统计图第六部分，学习统计
     */
    @GetMapping("/data6")
    public Result<TotalVo> data6(){

        Map map= new HashMap();


        //金职大讲堂统计
        Integer jzdjt = coursesService.selectBrowseNumTotal(1);

        //职业技能等级
        Integer zyjn = coursesService.selectBrowseNumTotal(3);

        //产后恢复
        Integer chhf = coursesService.selectBrowseNumTotal(5);

        //幼儿照护
        Integer yezh = coursesService.selectBrowseNumTotal(2);

        //职业资格课程
        Integer zyzg = coursesService.selectBrowseNumTotal(4);


        List<TotalVo> totalVos =new ArrayList<>();
        TotalVo totalVo1 =new TotalVo();
        totalVo1.setName("金职大讲堂");
        totalVo1.setValue(jzdjt);

        TotalVo totalVo2 =new TotalVo();
        totalVo2.setName("职业技能等级");
        totalVo2.setValue(zyjn);

        TotalVo totalVo3 =new TotalVo();
        totalVo3.setName("产后恢复课程");
        totalVo3.setValue(chhf);

        TotalVo totalVo4 =new TotalVo();
        totalVo4.setName("幼儿照护课程");
        totalVo4.setValue(yezh);

        TotalVo totalVo5 =new TotalVo();
        totalVo5.setName("职业资格课程");
        totalVo5.setValue(zyzg);

//        TotalVo totalVo6 =new TotalVo();
//        totalVo6.setName("总计");
//        totalVo6.setValue(jzdjt+zyjn+chhf+yezh+zyzg);

        totalVos.add(totalVo1);
        totalVos.add(totalVo2);
        totalVos.add(totalVo3);
        totalVos.add(totalVo4);
        totalVos.add(totalVo5);




        TotalVo rstTotalVo =new TotalVo();
        rstTotalVo.setSumTotal(jzdjt+zyjn+chhf+yezh+zyzg);
        rstTotalVo.setTotal(totalVos);
        return Result.ok(rstTotalVo);
    }





    /**
     * 统计图第七部分，练题统计
     */
    @GetMapping("/data7")
    public Result<TotalVo> data7() {

        String key = "data7";

        TotalVo data = (TotalVo) RedisUtil.get(key);
        if (data!=null) {
            return Result.ok(data);
        }


        TotalVo totalVo = new TotalVo(); //定义最终返回结果

        //数据初始化
        List listY = new ArrayList();
        listY.add("初级");
        listY.add("中级");
        listY.add("高级");
        listY.add("初级");
        listY.add("中级");
        listY.add("高级");

        List listYrzh =new ArrayList();
        listYrzh.add(0);
        listYrzh.add(0);
        listYrzh.add(0);
        listYrzh.add(0);
        listYrzh.add(0);
        listYrzh.add(0);

        List listChhf=new ArrayList();
        listChhf.add(0);
        listChhf.add(0);
        listChhf.add(0);
        listChhf.add(0);
        listChhf.add(0);
        listChhf.add(0);

        List<Data7Vo> data7Vos = examinationAnswerSheetPracticeService.exSheettotal();
        for (int i = 0; i < listY.size(); i++) {
            if (i >= 0 && i < data7Vos.size() && data7Vos.get(i) != null) {
                if (data7Vos.get(i).getProfileId().equals(1241245212023312386L)) {//幼儿照护
                    if (data7Vos.get(i).getGrade() == 0) {  //高
                        listYrzh.set(2, data7Vos.get(i).getCount());
                    }

                    if (data7Vos.get(i).getGrade() == 1) {  //中
                        listYrzh.set(1, data7Vos.get(i).getCount());
                    }

                    if (data7Vos.get(i).getGrade() == 2) {  //初
                        listYrzh.set(0, data7Vos.get(i).getCount());
                    }
                } else { //产后恢复
                    if (data7Vos.get(i).getGrade() == 0) {  //高
                        listChhf.set(5, data7Vos.get(i).getCount());
                    }

                    if (data7Vos.get(i).getGrade() == 1) {  //中
                        listChhf.set(4, data7Vos.get(i).getCount());
                    }

                    if (data7Vos.get(i).getGrade() == 2) {  //初
                        listChhf.set(3, data7Vos.get(i).getCount());
                    }
                }
            }
        }
        totalVo.setY(listY);
        totalVo.setYrzh(listYrzh);
        totalVo.setChhf(listChhf);

        RedisUtil.set(key,totalVo,calculateSecondsUntil11PM(LocalDateTime.now()));

        return Result.ok(totalVo);
    }






    public static TotalVo formatData(List<Map<Object, Object>> data,int type) {

        // 准备两个列表，一个用于存放省份信息，一个用于存放统计信息
        /** 省份 Y轴*/
        List<String> Y =new ArrayList<>();

        /** 人数 X轴*/
        List<String> X = new ArrayList<>();

        // 遍历数据列表
        for (Map<Object, Object> entry : data) {
            // 获取省份和报名人数
            for (Map.Entry<Object, Object> pair : entry.entrySet()) {
                String province = pair.getKey().toString();
                if (province.equals("province")){ //省份
                    Y.add(pair.getValue().toString());
                }

                if (province.equals("stuCount")){ //人数统计
                    if (pair.getValue() instanceof Long) {
                        Long value = (Long) pair.getValue();
                        if (type == 2) { // 师资
                            value = value + 80L;
                        }
                        X.add(String.valueOf(value));
                    } else if (pair.getValue() instanceof Integer) {
                        Integer value = (Integer) pair.getValue();
                        if (type == 2) { // 师资
                            value = value + 80;
                        }
                        X.add(String.valueOf(value));
                    } else {
                        X.add(pair.getValue().toString());
                    }
                }
            }
        }
        // 将两个Map加入到formattedData中
        TotalVo totalVo =new TotalVo();
        totalVo.setX(X);
        totalVo.setY(Y);
        return totalVo;
    }




}
